package com.henghe.frame.ddl.util.mysql;

import com.henghe.frame.common.util.PattenUtil;
import com.henghe.frame.ddl.constant.DdlConstant;
import com.henghe.frame.ddl.pojo.ColumnVo;
import com.henghe.frame.ddl.pojo.TableColumnEntity;
import com.henghe.frame.ddl.pojo.TableEntity;
import com.henghe.frame.ddl.pojo.mysql.MysqlTableEntity;
import com.henghe.frame.ddl.util.DbUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * Description:
 * Author: LiuWenQing
 * Datetime: 2024/6/5 10:36
 */
@Slf4j
public class MysqlDdlUtil extends DbUtil {

    public static List<Class> generatorClasses = Arrays.asList(int.class,
            Integer.class, String.class, Long.class, long.class, BigDecimal.class, Date.class, LocalDateTime.class);

    /**
     * 扫描注解后，获取表实体集合
     *
     * @param path
     * @param engineType
     * @return
     */
    public static List<TableEntity> getCodeDb(String path, String engineType) {
        return searchPackageEntities(path, DdlConstant.MYSQL, engineType, generatorClasses, null, null);
    }

    /**
     * 检查是否相等
     *
     * @param tableColumnEntity
     * @param columnVo
     * @return
     */
    public static Boolean columnCheck(TableColumnEntity tableColumnEntity, ColumnVo columnVo) {
        // 判断字段类型
        if (tableColumnEntity.getType().equals("varchar") &&
                !(DdlConstant.MysqlStrTypes.contains(columnVo.getDataType().trim())))
            return Boolean.FALSE;
        if (!tableColumnEntity.getType().toLowerCase().equals(columnVo.getDataType().toLowerCase()))
            return Boolean.FALSE;

        // 判断字段长度
//        if (StringUtils.isNotEmpty(tableColumnEntity.getLength()) &&
//                !tableColumnEntity.getLength().equals(columnVo.getLength()))
//            return Boolean.FALSE;

        // 判断是否可为空
        if (!tableColumnEntity.getIsNotNull().equals(columnVo.getIsNotNull()))
            return Boolean.FALSE;

        // 判断默认值
        if (StringUtils.isNotEmpty(tableColumnEntity.getDefaultValue())
                && !tableColumnEntity.getDefaultValue().equals(columnVo.getDefaultValue()))
            return Boolean.FALSE;

        // 判断注释
        if (StringUtils.isNotEmpty(tableColumnEntity.getComment())
                && !tableColumnEntity.getComment().equals(columnVo.getComment()))
            return Boolean.FALSE;

        return Boolean.TRUE;
    }

    /**
     * 新增字段
     *
     * @param tableColumnEntity
     * @param tableName
     * @return
     */
    public static String addColumn(TableColumnEntity tableColumnEntity, String tableName) {
        String sql = "alter table " + tableName + " ADD " + tableColumnEntity.getName() + " " + tableColumnEntity.getType() + " ";
        if (StringUtils.isNotEmpty(tableColumnEntity.getLength()))
            sql += "(" + tableColumnEntity.getLength() + ") ";
        if (tableColumnEntity.getIsNotNull() != null && tableColumnEntity.getIsNotNull())
            sql += " not null ";
        if (StringUtils.isNotEmpty(tableColumnEntity.getDefaultValue())) {
            String valueStr = tableColumnEntity.getDefaultValue();
            Boolean needBrackets;
            if (valueStr.contains(".")) {
                needBrackets = !PattenUtil.isAllDigits(valueStr.replaceAll(".", ""));
            } else {
                needBrackets = !PattenUtil.isAllDigits(valueStr);
            }
            sql += "DEFAULT " + (needBrackets ? ("(" + valueStr + ")") : (valueStr)) + " ";
        }
        if (StringUtils.isNotEmpty(tableColumnEntity.getComment()))
            sql += "comment \'" + tableColumnEntity.getComment() + "\'";
        return sql;
    }

    /**
     * 删除字段
     *
     * @param columnVo
     * @param tableName
     * @return
     */
    public static String deleteColumn(ColumnVo columnVo, String tableName) {
        String sql = "alter table " + tableName + " drop column " + columnVo.getColumnName() + " ";
        return sql;
    }

    /**
     * 修改字段
     *
     * @param tableColumnEntity
     * @param tableName
     * @return
     */
    public static String updateColumn(TableColumnEntity tableColumnEntity, String tableName) {
        String sql = "alter table " + tableName + " modify " + tableColumnEntity.getName() + " " + tableColumnEntity.getType() + " ";
        if (StringUtils.isNotEmpty(tableColumnEntity.getLength()))
            sql += "(" + tableColumnEntity.getLength() + ") ";
        if (tableColumnEntity.getIsNotNull())
            sql += " not null ";
        if (StringUtils.isNotEmpty(tableColumnEntity.getDefaultValue())) {
            String valueStr = tableColumnEntity.getDefaultValue();
            Boolean needBrackets;
            if (valueStr.contains(".")) {
                needBrackets = !PattenUtil.isAllDigits(valueStr.replaceAll(".", ""));
            } else {
                needBrackets = !PattenUtil.isAllDigits(valueStr);
            }
            sql += "DEFAULT " + (needBrackets ? ("(" + valueStr + ")") : (valueStr)) + " ";
        }
        if (StringUtils.isNotEmpty(tableColumnEntity.getComment()))
            sql += "comment \'" + tableColumnEntity.getComment() + "\'";
        return sql;
    }

    /**
     * 生成建表语句
     *
     * @param mysqlTableEntities
     * @return
     */
    public static List<String> generateTables(List<MysqlTableEntity> mysqlTableEntities) {
        List<String> sqls = new ArrayList<>();
        for (MysqlTableEntity mysqlTableEntity : mysqlTableEntities) {
            String createTableSql = generateTable(mysqlTableEntity);
            if (StringUtils.isNotEmpty(createTableSql))
                sqls.add(createTableSql);
        }
        return sqls;
    }

    /**
     * 生成建表语句
     *
     * @param mysqlTableEntity
     * @return
     */
    public static String generateTable(MysqlTableEntity mysqlTableEntity) {
        StringBuffer stringBuffer = new StringBuffer("");
        stringBuffer.append("CREATE TABLE " + mysqlTableEntity.getTableName() + " (");
        List<TableColumnEntity> columns = mysqlTableEntity.getColumns();
        TableColumnEntity idColumn = columns.stream().filter(e -> e.getIsPrimaryKey() == true).findAny().orElse(null);
        if (idColumn == null)
            return "";
        for (TableColumnEntity column : columns) {
            stringBuffer.append(column.getName() + " " + column.getType());
            if (StringUtils.isNotEmpty(column.getLength()))
                stringBuffer.append("(" + column.getLength() + ")");
            if (column.getIsNotNull()) {
                stringBuffer.append(" NOT NULL");
            }
            if (StringUtils.isNotEmpty(column.getGenerateType()))
                stringBuffer.append(" " + column.getGenerateType());
            if (StringUtils.isNotEmpty(column.getDefaultValue()))
                stringBuffer.append(" DEFAULT '" + column.getDefaultValue() + "'");
            if (StringUtils.isNotEmpty(column.getComment()))
                stringBuffer.append(" comment \'" + column.getComment() + "\'");
            stringBuffer.append(",");
        }
        stringBuffer.append("PRIMARY KEY (`" + idColumn.getName() + "`)");
        stringBuffer.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8");
        return stringBuffer.toString();
    }


}
